{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "031e360d-e5bb-4c1d-be5a-018bd3f005f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch \n",
    "import numpy as np \n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9a18fb10-1d97-4fb8-b89a-a75f93870a06",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "8bf6d605-7c80-4fd4-932a-61c89e0a9f6d",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv('data/Income1.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "1206b5cb-182b-4869-91e1-684532e03553",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 30 entries, 0 to 29\n",
      "Data columns (total 3 columns):\n",
      " #   Column      Non-Null Count  Dtype  \n",
      "---  ------      --------------  -----  \n",
      " 0   Unnamed: 0  30 non-null     int64  \n",
      " 1   Education   30 non-null     float64\n",
      " 2   Income      30 non-null     float64\n",
      "dtypes: float64(2), int64(1)\n",
      "memory usage: 852.0 bytes\n"
     ]
    }
   ],
   "source": [
    "df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "id": "83140353-9739-45fc-ad10-bcea66651251",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这里除了将原来的数据转成二维向量外reshape动作，\n",
    "# 此时向量中的数据类型还是float64 需要转成tensor的相应数据类型FloatTensor\n",
    "\n",
    "X = torch.from_numpy(df.Education.values.reshape(-1,1)).type(torch.FloatTensor)\n",
    "Y = torch.from_numpy(df.Income.values.reshape(-1,1)).type(torch.FloatTensor)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "72a413f2-fdf1-42f0-bcf9-3c8ed1a028c2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[10.0000],\n",
       "         [10.4013],\n",
       "         [10.8428],\n",
       "         [11.2441],\n",
       "         [11.6455],\n",
       "         [12.0870],\n",
       "         [12.4883],\n",
       "         [12.8896],\n",
       "         [13.2910],\n",
       "         [13.7324],\n",
       "         [14.1338],\n",
       "         [14.5351],\n",
       "         [14.9766],\n",
       "         [15.3779],\n",
       "         [15.7793],\n",
       "         [16.2207],\n",
       "         [16.6221],\n",
       "         [17.0234],\n",
       "         [17.4649],\n",
       "         [17.8662],\n",
       "         [18.2676],\n",
       "         [18.7090],\n",
       "         [19.1104],\n",
       "         [19.5117],\n",
       "         [19.9130],\n",
       "         [20.3545],\n",
       "         [20.7559],\n",
       "         [21.1572],\n",
       "         [21.5987],\n",
       "         [22.0000]]),\n",
       " tensor([[26.6588],\n",
       "         [27.3064],\n",
       "         [22.1324],\n",
       "         [21.1698],\n",
       "         [15.1926],\n",
       "         [26.3990],\n",
       "         [17.4353],\n",
       "         [25.5079],\n",
       "         [36.8846],\n",
       "         [39.6661],\n",
       "         [34.3963],\n",
       "         [41.4980],\n",
       "         [44.9816],\n",
       "         [47.0396],\n",
       "         [48.2526],\n",
       "         [57.0343],\n",
       "         [51.4909],\n",
       "         [61.3366],\n",
       "         [57.5820],\n",
       "         [68.5537],\n",
       "         [64.3109],\n",
       "         [68.9590],\n",
       "         [74.6146],\n",
       "         [71.8672],\n",
       "         [76.0981],\n",
       "         [75.7752],\n",
       "         [72.4861],\n",
       "         [77.3550],\n",
       "         [72.1188],\n",
       "         [80.2606]]))"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X,Y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "92195932-5b22-4518-a0c7-dd5b9a124aab",
   "metadata": {},
   "outputs": [],
   "source": [
    "from torch import nn"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "aee83a32-ca0c-4bd9-9e67-1a31956d83e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "class IncomeModule(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.linear = nn.Linear(in_features=1,out_features=1)\n",
    "    def forward(self,input):\n",
    "        return self.linear(input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "6ef4ae04-a054-4951-a12a-6903f6c8957f",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = IncomeModule()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f4b59162-0014-441b-ad15-609794114616",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这是差平方的损失函数\n",
    "loss_fn = nn.MSELoss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "id": "61fb3d15-57d9-4072-a7bc-6ef4241c0315",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 随机梯度下降 优化器 ，优化器算法发展历程: SGD→SGDM→NAG→AdaGrad→AdaDelta→Adam→Nadam\n",
    "opt = torch.optim.SGD(params=model.parameters(),lr=0.001)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "9d31cdeb-3c62-4f82-9eae-9ce63e779a03",
   "metadata": {},
   "outputs": [],
   "source": [
    "for epoch in range(5000):\n",
    "    # zip 是将所有参数的对应元素打包成一个元组，将这些元组组成列表\n",
    "    for x,y in zip(X,Y):\n",
    "        x.shape,y.shape\n",
    "        y_gred = model(x)\n",
    "        loss = loss_fn(y_gred,y)\n",
    "        # 将之前的梯度信息清零\n",
    "        opt.zero_grad()\n",
    "        # 反向传播\n",
    "        loss.backward()\n",
    "        opt.step()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "id": "77ab467c-0cf2-4969-b7ac-b3c08189cf79",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Parameter containing:\n",
       " tensor([[5.1267]], requires_grad=True),\n",
       " Parameter containing:\n",
       " tensor([-32.6979], requires_grad=True)]"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(model.parameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "id": "95186a9c-9924-4d92-ae41-bf5c6c5c855f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[('linear.weight',\n",
       "  Parameter containing:\n",
       "  tensor([[5.1267]], requires_grad=True)),\n",
       " ('linear.bias',\n",
       "  Parameter containing:\n",
       "  tensor([-32.6979], requires_grad=True))]"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# named_parameters() 函数可以打印出来参数名称\n",
    "list(model.named_parameters())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "9db714c6-6004-4f42-97a2-abca5b2646ba",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(0     10.000000\n",
       " 1     10.401338\n",
       " 2     10.842809\n",
       " 3     11.244147\n",
       " 4     11.645485\n",
       " 5     12.086957\n",
       " 6     12.488294\n",
       " 7     12.889632\n",
       " 8     13.290970\n",
       " 9     13.732441\n",
       " 10    14.133779\n",
       " 11    14.535117\n",
       " 12    14.976589\n",
       " 13    15.377926\n",
       " 14    15.779264\n",
       " 15    16.220736\n",
       " 16    16.622074\n",
       " 17    17.023411\n",
       " 18    17.464883\n",
       " 19    17.866221\n",
       " 20    18.267559\n",
       " 21    18.709030\n",
       " 22    19.110368\n",
       " 23    19.511706\n",
       " 24    19.913043\n",
       " 25    20.354515\n",
       " 26    20.755853\n",
       " 27    21.157191\n",
       " 28    21.598662\n",
       " 29    22.000000\n",
       " Name: Education, dtype: float64,\n",
       " array([10.        , 10.40133779, 10.84280936, 11.24414716, 11.64548495,\n",
       "        12.08695652, 12.48829431, 12.88963211, 13.2909699 , 13.73244147,\n",
       "        14.13377926, 14.53511706, 14.97658863, 15.37792642, 15.77926421,\n",
       "        16.22073579, 16.62207358, 17.02341137, 17.46488294, 17.86622074,\n",
       "        18.26755853, 18.7090301 , 19.11036789, 19.51170569, 19.91304348,\n",
       "        20.35451505, 20.75585284, 21.15719064, 21.59866221, 22.        ]))"
      ]
     },
     "execution_count": 81,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# df.Education 这个是Series \n",
    "# df.Education.values则是数组输出形式\n",
    "df.Education,df.Education.values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "dcec30e7-6852-41ea-b94d-3cca10932ffa",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[10.0000],\n",
       "         [10.4013],\n",
       "         [10.8428],\n",
       "         [11.2441],\n",
       "         [11.6455],\n",
       "         [12.0870],\n",
       "         [12.4883],\n",
       "         [12.8896],\n",
       "         [13.2910],\n",
       "         [13.7324],\n",
       "         [14.1338],\n",
       "         [14.5351],\n",
       "         [14.9766],\n",
       "         [15.3779],\n",
       "         [15.7793],\n",
       "         [16.2207],\n",
       "         [16.6221],\n",
       "         [17.0234],\n",
       "         [17.4649],\n",
       "         [17.8662],\n",
       "         [18.2676],\n",
       "         [18.7090],\n",
       "         [19.1104],\n",
       "         [19.5117],\n",
       "         [19.9130],\n",
       "         [20.3545],\n",
       "         [20.7559],\n",
       "         [21.1572],\n",
       "         [21.5987],\n",
       "         [22.0000]]),\n",
       " tensor([[18.5690],\n",
       "         [20.6265],\n",
       "         [22.8898],\n",
       "         [24.9473],\n",
       "         [27.0049],\n",
       "         [29.2682],\n",
       "         [31.3257],\n",
       "         [33.3832],\n",
       "         [35.4408],\n",
       "         [37.7041],\n",
       "         [39.7616],\n",
       "         [41.8191],\n",
       "         [44.0824],\n",
       "         [46.1400],\n",
       "         [48.1975],\n",
       "         [50.4608],\n",
       "         [52.5183],\n",
       "         [54.5758],\n",
       "         [56.8391],\n",
       "         [58.8967],\n",
       "         [60.9542],\n",
       "         [63.2175],\n",
       "         [65.2750],\n",
       "         [67.3326],\n",
       "         [69.3901],\n",
       "         [71.6534],\n",
       "         [73.7109],\n",
       "         [75.7685],\n",
       "         [78.0317],\n",
       "         [80.0893]], grad_fn=<AddmmBackward0>))"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#\n",
    "# \n",
    "X,model(X)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "id": "fab10345-6296-408c-ada6-a1084607d287",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(df.Education.values,df.Income.values)\n",
    "plt.xlabel('Edu')\n",
    "plt.ylabel('Income')\n",
    "\n",
    "# \n",
    "# c='b' 指定输出blue蓝色 r：红色\n",
    "plt.plot(X,model(X).detach().numpy(),c='b')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "id": "cbf88611-ecc4-47b9-a50c-526a5609526f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([65.2219], grad_fn=<ViewBackward0>)"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 模型训练完成后，可以直接通过模型推断出 Edu 为 19.1 的情况下 income的值\n",
    "model(torch.tensor([19.1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "52d91151-dd17-4aaa-8256-3a8dfad1e8ae",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
